<template>
  <div>
    <q-splitter v-model="splitterModel" style="height: calc(100vh - 58px)">
      <template v-slot:before>
        <q-splitter v-model="leftModel" horizontal>
          <template v-slot:before>
            <q-item-label
              class="text-weight-bold text-body1 bg-purple text-white sticky text-uppercase"
              header
            >
              数据库表
            </q-item-label>
            <q-list bordered separator>
              <q-slide-item
                v-for="(table, index) in schemaTables"
                v-show="tableList.includes(table.TABLE_NAME)"
                :key="table.TABLE_NAME"
                bordered
                class="full-width"
                clickable
                dense
                left-color="red"
                right-color="purple"
                @click="selectTable(index)"
                @swipe="handleSwipe(index)"
              >
                <q-item
                  :active="tableSelected === table.TABLE_NAME"
                  active-class="text-bold text-purple"
                >
                  <q-item-section avatar>
                    <q-icon color="primary" name="toc" />
                  </q-item-section>
                  <q-item-section>
                    {{ table.TABLE_NAME }}
                    {{ table.TABLE_COMMENT }}
                  </q-item-section>
                  <q-item-section side top>
                    <q-btn
                      :color="!table.generated ? 'red' : 'green'"
                      :icon="!table.generated ? 'lock' : 'lock_open'"
                      round
                      size="xs"
                      @click="genetated(index)"
                    />
                  </q-item-section>
                </q-item>
              </q-slide-item>
            </q-list>
          </template>

          <template v-slot:after>
            <q-splitter v-model="leftInsideModel" horizontal>
              <template v-slot:before>
                <q-item-label class="text-weight-bold text-uppercase" header>
                  {{ tableSelected }} 表参数
                </q-item-label>
                <div
                  id="tableContainer"
                  style="
                    width: calc(100%);
                    height: calc(100% - 50px);
                    overflow: hidden;
                  "
                ></div>
              </template>

              <template v-slot:after>
                <q-item-label class="text-weight-bold text-uppercase" header>
                  自定义参数
                  <q-btn
                    class="float-right"
                    label="执行"
                    size="sm"
                    @click="execute"
                  />
                </q-item-label>
                <div
                  id="defineContainer"
                  style="
                    width: calc(100%);
                    height: calc(100% - 50px);
                    overflow: hidden;
                  "
                ></div>
              </template>
            </q-splitter>
          </template>
        </q-splitter>
      </template>

      <template v-slot:after>
        <q-splitter v-model="insideModel" horizontal>
          <template v-slot:before>
            <div style="width: 100%; height: 100%">
              <q-toolbar class="bg-purple text-white">
                <q-btn
                  @click="generate"
                />
                <q-btn
                  dense
                  flat
                  label="代码生成"
                  size="md"
                  :loading="gen" color="red" @click="generate">
                  代码生成
                  <template v-slot:loading>
                    Loading...
                  </template>
                </q-btn>
                <q-separator class="q-ma-sm" color="orange" inset vertical />
                <q-input
                  v-model="renderDebounce"
                  bg-color="white"
                  dense
                  label="渲染间隔"
                  outlined
                  style="width: 90px"
                />
                <q-space />
                <q-tabs v-model="tab" shrink>
                  <q-tab
                    v-for="(item, index) in templates"
                    :key="index"
                    :label="item.component"
                    :name="item.name"
                    inline-label
                  >
                  </q-tab>
                  <!--                 @click="test" -->
                </q-tabs>
              </q-toolbar>

              <ql-editor
                ref="templateEditor"
                :debounce="renderDebounce"
                :editor-id="'editor' + 1"
                :on-chang-content="onTemplateContentChange"
                :path="templatePath"
                style="height: calc(100% - 50px); width: 100%"
              />
              <!--              <q-tab-panels  style="width: 100%;height: calc(100% - 50px);" v-model="tab" animated>-->
              <!--                <q-tab-panel v-for="(item,index) in templates" :key="index"  class="q-pa-none" :name="item.name">-->
              <!--                  -->
              <!--                </q-tab-panel>-->
              <!--              </q-tab-panels>-->
            </div>
          </template>

          <template v-slot:after>
            <ql-editor
              ref="renderEditor"
              :editor-id="'editor' + 2"
              :path="renderPath"
              style="height: calc(100% - 50px); width: 100%"
            >
            </ql-editor>
            <q-toolbar class="bg-purple-4 text-white text-weight-light">
              文件路径:{{ renderPath }}
            </q-toolbar>
          </template>
        </q-splitter>
      </template>
    </q-splitter>
  </div>
</template>
<script lang="ts" setup>
import * as monaco from 'monaco-editor';
import { editor } from 'monaco-editor';
import { onMounted, Ref, ref, toRaw, watch } from 'vue';
import { Database, SchemaTableList, SchemaTables } from 'src/models/Orm';
import { date, LocalStorage, useQuasar } from 'quasar';
import { outTables, outTemplate } from 'src/models/File';
import QlEditor from 'components/QlEditor.vue';

const tab = ref('c1');
const renderDebounce = ref(10);
const templatePath = ref('');
const renderPath = ref('');
const templateEditor = ref(null);
const renderEditor = ref(null);
const splitterModel = ref(33);
const insideModel = ref(33);
const leftModel = ref(25);
const leftInsideModel = ref(60);
const tableList = ref([] as string[]);
const tableSelected = ref('');
const templates = ref([] as outTemplate[]);
const project = ref(null as project | null);
let prent = '';
let author = '';
let path = '';
let timer: string | number | NodeJS.Timer | undefined;
let editor: editor.IStandaloneCodeEditor | null = null;
let tableEditor: editor.IStandaloneCodeEditor | null = null;
let defineEditor: editor.IStandaloneCodeEditor | null = null;
let finalEditor: editor.IStandaloneCodeEditor | null = null;
let tableData: SchemaTables | null = null;
const schemaTables: Ref<SchemaTableList | null> = ref(null);
const config_tables_generate_log: Ref<outTables[] | []> = ref([]);
const handleSwipe = (index: number) => {
  console.log('滑动项的索引：', index);
};
const execute = async () => {
  let data = await window.ipcCom.execute(defineEditor?.getValue())
  console.log(data);
  tableEditor?.setModel(monaco.editor.createModel(data, 'text/plain'));
};
const notion = () => {
  window.ipcCom.notion();
};
const genetated = (index: number) => {
  schemaTables.value[index].generated = !schemaTables.value[index].generated;
  let log = [] as string[];
  schemaTables.value?.forEach((i) => {
    if (i.generated) {
      log.push(i.TABLE_NAME);
    }
  });
  LocalStorage.set('config_tables_generate_log', log);
};
// function finalize(reset: () => void) {
//   timer = setTimeout(() => {
//     reset();
//   }, 1000);
// }
//
// onBeforeUnmount(() => {
//   clearTimeout(timer);
// });
//
// const onLeft = ({ reset }) => {
//   $q.notify('Left action triggered. Resetting in 1 second.');
//   finalize(reset);
// };
//
// const onRight = (details) => {
//   console.log(details);
//   // finalize(reset);
// };
const onTemplateContentChange = async () => {
  await templateEditor.value?.saveEditorContent();
  await renderTemplate();
  await renderEditor.value?.refreshContent();
};
const test = async () => {
  await window.ipcCom.test();
};
watch(tab, (newVal) => {
  let newModel: outTemplate | undefined = templates.value.find((i) => {
    return i.name == newVal;
  });

  function getPostfix() {
    let res = '';
    if (newModel.postfix) {
      res = capitalizeFirstLetter(underscoreToCamelCase(newModel.component));
    }
    return res;
  }

  if (tableSelected.value) {
    if (newModel) {
      let outputPath = (
        project.value?.path.root +
        '.' +
        prent +
        '.' +
        newModel.outputPath
      ).replaceAll('.', '\\');

      renderPath.value =
        outputPath +
        '\\' +
        capitalizeFirstLetter(underscoreToCamelCase(tableSelected.value)) +
        getPostfix() +
        '.' +
        newModel.path.split('.').reverse()[0];
    }
  }
  if (newModel) templatePath.value = newModel.path;
});

const renderTemplate = async () => {
  let res = await window.ipcCom.getRenderTemplate(templatePath.value, {
    ...toRaw(tableData),
    ...new Function('return' + defineEditor?.getValue())(),
  });
  console.log(res);
  let result = await window.ipcCom.saveFileText(toRaw(renderPath.value), res);
  console.log(result);
  finalEditor?.setValue(res);
  // console.log(res);
};
const JoinPath = (url: string[]): string => {
  return window.ipcCom.pathJoin(url);
};
// 生成代码
const generate = async () => {
  console.log('代码生成开始');
  // 需要生成的表
  let generateTable = schemaTables.value?.filter((i) => {
    return tableList.value.includes(i.TABLE_NAME);
  });
  // 每个表生成的模板
  let generateTemplate = templates.value;
  console.log('生成模板：', generateTemplate);
  console.log('生成表：', generateTable);
  console.log(
    '自定义属性',
    new Function('return' + defineEditor?.getValue())()
  );
  console.log('项目目录', project.value?.path.root);

  if (generateTable) {
    let log = [] as string[];

    // 表循环
    for (let i of generateTable) {
      //定义首字母大写的驼峰
      i.TABLE_NAME_INITIALS_HUMP = capitalizeFirstLetter(
        underscoreToCamelCase(i.TABLE_NAME)
      );
      //定义驼峰
      i.TABLE_NAME_HUMP = underscoreToCamelCase(i.TABLE_NAME);
      // 表字段循环添加属性
      i.tables.forEach((j) => {
        //定义首字母大写的驼峰
        j.TABLE_NAME_INITIALS_HUMP = capitalizeFirstLetter(
          underscoreToCamelCase(j.TABLE_NAME)
        );
        //定义驼峰
        j.TABLE_NAME_HUMP = underscoreToCamelCase(j.TABLE_NAME);
      });
      // 生成表的组件代码
      for (let j of generateTemplate) {
        function getPostfix() {
          return j.postfix
            ? capitalizeFirstLetter(underscoreToCamelCase(j.component))
            : '';
        }

        let outPath = JoinPath([
          project.value?.path.root || '',
          ...prent.split('.'),
          ...j.outputPath.split('.'),
          i.TABLE_NAME_INITIALS_HUMP +
            '' +
            getPostfix() +
            '.' +
            j.path.split('.').reverse()[0],
        ]);
        let templatePath = j.path;

        console.log('模板目录：' + templatePath + '输出目录：' + outPath);
        console.log(
          await templateGenerator(templatePath, outPath, {
            ...toRaw(tableData),
            ...new Function('return' + defineEditor?.getValue())(),
          })
        );
      }
      log.push(i.TABLE_NAME);
    }
    LocalStorage.set('config_tables_generate_log', log);
    schemaTables.value?.forEach((i) => {
      i.generated = log.includes(i.TABLE_NAME);
    });
  }

  // for (let i = 0; i < tableList.value.length; i++) {
  //   let table = tableList.value[i];
  //   let res = await window.ipcCom.getRenderTemplate(templatePath.value, {
  //     ...toRaw(tableData),
  //     ...new Function('return' + defineEditor?.getValue())(),
  //   });
  //   console.log(res);
  //   let result = await window.ipcCom.saveFileText(toRaw(renderPath.value), res);
  //   console.log(result);
  //   finalEditor?.setValue(res);
  //   console.log(res);

  // let res = await window.ipcCom.getRenderTemplate(templatePath.value, {
  //   ...toRaw(tableData),
  //   ...new Function('return' + defineEditor?.getValue())(),
  // });
  // console.log(res);
  // let result = await window.ipcCom.saveFileText(toRaw(renderPath.value), res);
  // console.log(result);
  // finalEditor?.setValue(res);
  // console.log(res);
};
/*
 * templateGenerator 根据模板生成文件
 * @param templatePath 模板路径
 * @param outPath 输出路径
 * @param data 自定义数据+表数据
 * */
const templateGenerator = async (
  templatePath: string,
  outPath: string,
  data: object
) => {
  // templatePath: string,
  // outPath: string,
  // data: object
  await window.ipcCom.templateGenerator(templatePath, outPath, data);
};

function underscoreToCamelCase(str: string) {
  return str.replace(/_([a-z])/g, function (match, letter) {
    return letter.toUpperCase();
  });
}

function capitalizeFirstLetter(str: string) {
  return str.charAt(0).toUpperCase() + str.slice(1);
}

watch(tableSelected, () => {
  function getPostfix() {
    let res = '';
    if (newModel.postfix) {
      res = capitalizeFirstLetter(underscoreToCamelCase(newModel.component));
    }
    return res;
  }

  let newModel: outTemplate | undefined = templates.value.find((i) => {
    return i.name == tab.value;
  });

  if (tableSelected.value) {
    if (newModel) {
      let outputPath = (
        project.value?.path.root +
        '.' +
        prent +
        '.' +
        newModel.outputPath
      ).replaceAll('.', '\\');

      renderPath.value =
        outputPath +
        '\\' +
        capitalizeFirstLetter(underscoreToCamelCase(tableSelected.value)) +
        getPostfix() +
        '.' +
        newModel.path.split('.').reverse()[0];
    }
  }
});
const selectTable = (index: number) => {
  let tables: SchemaTables = schemaTables.value[index];
  tableSelected.value = tables.TABLE_NAME;

  tables.TABLE_NAME_HUMP = underscoreToCamelCase(tables.TABLE_NAME);
  tables.TABLE_NAME_INITIALS_HUMP = capitalizeFirstLetter(
    underscoreToCamelCase(tables.TABLE_NAME)
  );
  tables.tables.forEach((i) => {
    i.COLUMN_NAME_HUMP = underscoreToCamelCase(i.COLUMN_NAME);
    i.COLUMN_NAME_INITIALS_HUMP = capitalizeFirstLetter(
      underscoreToCamelCase(i.COLUMN_NAME)
    );
    i.toString = function () {
      return `
    {
        TABLE_CATALOG:'${this.TABLE_CATALOG}',
        TABLE_SCHEMA:'${this.TABLE_SCHEMA}',
        TABLE_NAME:'${this.TABLE_NAME}',
        COLUMN_NAME:'${this.COLUMN_NAME}',
        COLUMN_NAME_HUMP:'${underscoreToCamelCase(this.COLUMN_NAME)}',
        COLUMN_NAME_INITIALS_HUMP:'${capitalizeFirstLetter(
          underscoreToCamelCase(this.COLUMN_NAME)
        )}',
        ORDINAL_POSITION:'${this.ORDINAL_POSITION}',
        COLUMN_DEFAULT:'${this.COLUMN_DEFAULT}',
        IS_NULLABLE:'${this.IS_NULLABLE}',
        DATA_TYPE:'${this.DATA_TYPE}',
        CHARACTER_MAXIMUM_LENGTH:'${this.CHARACTER_MAXIMUM_LENGTH}',
        CHARACTER_OCTET_LENGTH:'${this.CHARACTER_OCTET_LENGTH}',
        NUMERIC_PRECISION:'${this.NUMERIC_PRECISION}',
        NUMERIC_SCALE:'${this.NUMERIC_SCALE}',
        DATETIME_PRECISION:'${this.DATETIME_PRECISION}',
        CHARACTER_SET_NAME:'${this.CHARACTER_SET_NAME}',
        COLLATION_NAME:'${this.COLLATION_NAME}',
        COLUMN_TYPE:'${this.COLUMN_TYPE}',
        COLUMN_KEY:'${this.COLUMN_KEY}',
        EXTRA:'${this.EXTRA}',
        PRIVILEGES:'${this.PRIVILEGES}',
        COLUMN_COMMENT:'${this.COLUMN_COMMENT}',
        GENERATION_EXPRESSION:'${this.GENERATION_EXPRESSION}',
        SRS_ID:'${this.SRS_ID}'
    }
    `;
    };
  });
  tables.toString = function () {
    return `{
    TABLE_CATALOG:'${this.TABLE_CATALOG}',
    TABLE_SCHEMA:'${this.TABLE_SCHEMA}',
    TABLE_NAME:'${this.TABLE_NAME}',
    TABLE_TYPE:'${this.TABLE_TYPE}',
    TABLE_NAME_HUMP:'${underscoreToCamelCase(this.TABLE_NAME)}',
    TABLE_NAME_INITIALS_HUMP:'${capitalizeFirstLetter(
      underscoreToCamelCase(this.TABLE_NAME)
    )}',
    ENGINE:'${this.ENGINE}',
    VERSION:'${this.VERSION}',
    ROW_FORMAT:'${this.ROW_FORMAT}',
    TABLE_ROWS:'${this.TABLE_ROWS}',
    AVG_ROW_LENGTH:'${this.AVG_ROW_LENGTH}',
    DATA_LENGTH:'${this.DATA_LENGTH}',
    MAX_DATA_LENGTH:'${this.MAX_DATA_LENGTH}',
    INDEX_LENGTH:'${this.INDEX_LENGTH}',
    DATA_FREE:'${this.DATA_FREE}',
    AUTO_INCREMENT:'${this.AUTO_INCREMENT}',
    CREATE_TIME:'${this.CREATE_TIME}',
    UPDATE_TIME:'${this.UPDATE_TIME}',
    CHECK_TIME:'${this.CHECK_TIME}',
    TABLE_COLLATION:'${this.TABLE_COLLATION}',
    CHECKSUM:'${this.CHECKSUM}',
    CREATE_OPTIONS:'${this.CREATE_OPTIONS}',
    TABLE_COMMENT:'${this.TABLE_COMMENT}',
    tables:'[${this.tables}]'
}
    `;
  };
  tableData = tables;
  // console.log(tables.toString());
  tableEditor?.setValue(tableData.toString());
};
window.DateFormat = (format: string) => {
  return date.formatDate(new Date(), format);
};
const initSchemaTable = async () => {
  let info = await sysConfigStore.getInfo(path);
  prent = info.output.parent;
  author = info.output.author;
  project.value = info.project;

  tableList.value = info.output.tables as string[];
  templates.value = info.output.templates;
  templates.value.forEach((i) => {
    console.log(i.path);
  });

  // console.log('templates', templates.value);
  // console.log('tableList.value',tableList.value);
  // console.log(info.database);

  // host: '120.79.244.217',
  //   user: 'mall',
  //   password: 'NrGJeKxy2SMsK6sT',
  //   database: 'mall',
  let datasource: Database = {
    host: info.database.host,
    username: info.database.username,
    password: info.database.password,
    database: info.database.database,
  };
  // console.log(await window.ipcCom.test(datasource));
  schemaTables.value = await window.ipcCom.getConnection(datasource);
  console.log(
    "LocalStorage.getItem('config_tables_generate_log') as string[];",
    LocalStorage.getItem('config_tables_generate_log') as string[]
  );
  let log = LocalStorage.getItem('config_tables_generate_log') as string[];
  schemaTables.value?.forEach((i) => {
    i.generated = log?.includes(i.TABLE_NAME);
  });
  // console.log(schemaTables.value);

  selectTable(
    schemaTables.value?.findIndex((i) => {
      return tableList.value[0] === i.TABLE_NAME;
    }) || 0
  );
  tab.value = templates.value[0].name;
  templatePath.value = templates.value[0].path;

  function getPostfix() {
    let res = '';
    if (templates.value[0].postfix) {
      res = capitalizeFirstLetter(
        underscoreToCamelCase(templates.value[0].component)
      );
    }
    return res;
  }

  let outputPath = (
    project.value.path.root +
    '.' +
    prent +
    '.' +
    templates.value[0].outputPath
  ).replaceAll('.', '\\');
  renderPath.value =
    outputPath +
    getPostfix() +
    '.' +
    templates.value[0].path.split('.').reverse()[0];
};
const editorValue = ref('');
const initEditor = () => {
  const resizeObserver = new ResizeObserver(() => {
    // 在这里添加你想要执行的改变大小的逻辑
    tableEditor?.layout();
    defineEditor?.layout();
  });

  resizeObserver.observe(
    document.getElementById('tableContainer') as HTMLDivElement
  );
  resizeObserver.observe(
    document.getElementById('defineContainer') as HTMLDivElement
  );
  tableEditor = monaco.editor.create(
    document.getElementById('tableContainer') as HTMLDivElement,
    {
      value: "'无数据，请选择表'",
      language: 'javascript',
    }
  );

  defineEditor = monaco.editor.create(
    document.getElementById('defineContainer') as HTMLDivElement,
    {
      value: 'ipconfig',
      language: 'javascript',
    }
  );

  // finalEditor.onDidScrollChange(() => {
  //   const scrollPosition = finalEditor?.getScrollTop();
  // //   console.log(scrollPosition);
  //   editor?.revealLineInCenterIfOutsideViewport(scrollPosition as number);
  // });
  // editor.onDidScrollChange(() => {
  //   const scrollPosition = editor?.getScrollTop();
  // //   console.log(scrollPosition);
  //   finalEditor?.revealLineInCenterIfOutsideViewport(scrollPosition as number);
  // });
  window.addEventListener('resize', () => {
    editor?.layout();
    tableEditor?.layout();
    defineEditor?.layout();
  });
  console.log(date.formatDate(Date.now(), 'YYYY-MM-DD HH:mm:ss').toString());
  //
};
watch(renderDebounce, () => {
  LocalStorage.set('renderDebounce', toRaw(renderDebounce.value));
});
onMounted(async () => {
  path =
    (LocalStorage.getItem('configFilePath') as string) ||
    (LocalStorage.getItem('CONFIG_FILE_PATH') as string);
  initEditor();
  config_tables_generate_log.value = LocalStorage.getItem(
    'config_tables_generate_log'
  );
  window.ipcCom.getFileText(path, false).then((res: string) => {
    editorValue.value = res;
    editor?.onDidChangeModelContent(
      (e: monaco.editor.IModelContentChangedEvent) => {
        // console.log('Editor model content changed:', e.changes);
        window.ipcCom.saveFileText(path, `${editor?.getValue()}`);
        // console.log(editor?.getValue());
      }
    );
  });

  renderDebounce.value =
    (LocalStorage.getItem('renderDebounce') as number) || 10;
  await initSchemaTable();
});
</script>
